/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  MixedQuoteModel.cpp
 *Author	:  yanyan.shen
 *Version	:  1.0
 *Date		:  2024/10/08
 *Desc		:  //������Ҫ˵���˳����ļ���ɵ���Ҫ����
 *Relation :
 *Others	:  //��������˵��
 *Function :  //��Ҫ�����б���ÿ����¼Ӧ���������������ܼ�Ҫ˵��
 *History	:
 * //�޸���ʷ��¼�б���ÿ���޸ļ�¼Ӧ�����޸����ڡ��޸��߼��޸����ݼ��
 ***************************************************************************************************/
#include "MixedQuoteModel.h"

#include <bondlib/BestQuote/CBondFilter.h>
#include <bondlib/BestQuote/CBrokerKeyList.h>
#include <bondlib/SSVContainer.h>
#if defined(__APPLE__) || defined(__MACH__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif

#ifdef WIN32
#define BASSERT assert
#else
#define BASSERT  //
#endif

MixedQuoteModel::MixedQuoteModel(const CBrokerUnit& stUnit,
                                 const CSortInfoManager& sortInfo)
    : BestQuoteModel(stUnit, sortInfo) {
  UpdateBrokerList();
}

MixedQuoteModel::~MixedQuoteModel() {}

void MixedQuoteModel::ReloadRecordsByFilter(BLHCONDITION& blh, int nType,
                                            const char* szSearch, bool all) {
  CBondSourceAvailable source(blh);
  source.SetSearch(nType, szSearch);
  m_bond_filter->SetCondition(&blh, all);
  m_keys->ReloadsBrokerMixedBP(&source, m_bond_filter);
}
bool MixedQuoteModel::isExpanded(int id) {
  std::set<int>::iterator itBond = m_expandedBond.find(id);
  return itBond != m_expandedBond.end();
}

bool MixedQuoteModel::CheckExistMixedBestPricePush(
    BLHCONDITION& condStr, const QList<xQBMixedBestQuoteUnit_c>& qblist) {
  SSBrokerKeyVector vct_result, vct_resdel;
  CSSVContainer::availableBond().UpdateMixedBestPricePush(
      condStr, vct_result, vct_resdel, qblist, true);
  if (vct_result.m_vct.size() > 0) return true;

  for (int i = 0; i < (int)vct_resdel.m_vct.size(); i++) {
    if (IsExist(vct_resdel.m_vct[i])) return true;
  }

  return false;
}

bool MixedQuoteModel::UpdateMixedBestPricePush(
    BLHCONDITION& condStr, const QList<xQBMixedBestQuoteUnit_c>& qblist) {
  SSBrokerKeyVector vct_result, vct_resdel;

  CSSVContainer::availableBond().UpdateMixedBestPricePush(
      condStr, vct_result, vct_resdel, qblist, true);
  m_keys->Update(vct_result.m_vct, vct_resdel.m_vct);
  return !vct_result.m_vct.empty() || !vct_resdel.m_vct.empty();
}

void MixedQuoteModel::Sort() {
  std::string contributorId = m_filter.stBlh.GetContributorId();

  if (m_filter.stBlh.nQuotePriceType[0] != CBondContainer::QptAll) {
    BYTE btPriceFilter = 0;
    int sz = sizeof(m_filter.stBlh.nQuotePriceType) / sizeof(int);
    for (int i = 0; i < sz; i++) {
      switch (m_filter.stBlh.nQuotePriceType[i]) {
        case CBondContainer::QptRealoffer:
          btPriceFilter |= 0x10;
          break;
        case CBondContainer::QptPart:
          btPriceFilter |= 0x20;
          break;
        case CBondContainer::QptBargin:
          btPriceFilter |= 0x40;
          break;
        default:
          break;
      }
    }
    m_keys->Sort(contributorId, btPriceFilter);
  } else
    m_keys->Sort(contributorId);
}

int MixedQuoteModel::GetRowCount() {
  return m_keys->GetRowCount() + m_expandBroker.size() * m_expandedBond.size();
}

void MixedQuoteModel::GetRecordKeysImpl(int row, int count,
                                        CBrokerKeyVector& keys) {
  keys.clear();
  if (count <= 0) return;

  int brokerCount = m_expandBroker.size();
  int recCount = m_keys->GetRowCount();
  int totalLine = GetRowCount();

  std::set<int> setLine;
  for (std::set<int>::iterator itBond = m_expandedBond.begin();
       itBond != m_expandedBond.end(); ++itBond) {
    BrokerKeyInfo tmpKey("", *itBond);
    int id = m_keys->Find(tmpKey);
    setLine.insert(id);
  }

  std::vector<int> vctTemp;
  int index = 0;
  for (int index = 0; index < recCount; index++) {
    if (setLine.find(index) != setLine.end()) {
      vctTemp.push_back(index * 10);
      for (int i = 1; i <= brokerCount; i++) {
        vctTemp.push_back(index * 10 + i);
      }
    } else
      vctTemp.push_back(index * 10);
  }
  BASSERT(vctTemp.size() == totalLine);
  if (totalLine == 0) return;
  BASSERT(row >= 0 && (vctTemp.size() == 0 || row < vctTemp.size()));

#ifdef WIN32
  int lineTo = min(row + count, vctTemp.size() - 1);
#else
  int lineTo = std::min((int)(row + count), (int)(vctTemp.size() - 1));
#endif

  int reqFrom = vctTemp[row] / 10;
  int reqTo = vctTemp[lineTo] / 10;
  int reqCount = reqTo - reqFrom + 1;
  int deltaRow = ((vctTemp[row] % 10) == 0 ? 0 : (vctTemp[row] % 10));
  BASSERT(reqCount > 0);

#ifdef WIN32
  BrokerKeyInfo* bkis =
      (BrokerKeyInfo*)_alloca(reqCount * sizeof(BrokerKeyInfo));
#else
  BrokerKeyInfo* bkis =
      (BrokerKeyInfo*)alloca(reqCount * sizeof(BrokerKeyInfo));
#endif

  memset(bkis, 0, reqCount * sizeof(BrokerKeyInfo));
  int nsize = m_keys->GetRecordKeys(reqFrom, reqCount, bkis);
  int dRow = m_keys->GetRowCount() - nsize;

  for (int i = 0; i < nsize; i++) {
    BrokerKeyInfo& bki = bkis[i];
    char buf[32] = {0};

#ifdef WIN32
    _itoa_s(bki.m_nBrokerId, buf, 31, 10);
#else
    sprintf(buf, "%d", bki.m_nBrokerId);
#endif

    if (deltaRow > 0) {
      for (std::vector<int>::iterator itBroker = m_expandBroker.begin();
           itBroker != m_expandBroker.end(); ++itBroker) {
        deltaRow--;
        if (deltaRow > 0) continue;
#ifdef WIN32
        _itoa_s(*itBroker, buf, 31, 10);
#else
        sprintf(buf, "%d", *itBroker);
#endif
        keys.push_back(BrokerKey(buf, bki.m_nIndex));
      }
      continue;
    }
    keys.push_back(BrokerKey(buf, bki.m_nIndex));
    if (m_expandedBond.find(bki.m_nIndex) != m_expandedBond.end()) {
      for (std::vector<int>::iterator itBroker = m_expandBroker.begin();
           itBroker != m_expandBroker.end(); ++itBroker) {
#ifdef WIN32
        _itoa_s(*itBroker, buf, 31, 10);
#else
        sprintf(buf, "%d", *itBroker);
#endif
        keys.push_back(BrokerKey(buf, bki.m_nIndex));
      }
    }
  }
}

void MixedQuoteModel::ExpandBond(const BrokerKey& key) {
  std::set<int>::iterator itBond = m_expandedBond.find(key.m_nIndex);
  if (itBond == m_expandedBond.end()) {
    m_expandedBond.clear();
    m_expandedBond.insert(key.m_nIndex);
  } else {
    m_expandedBond.clear();
    /// m_expandedBond.erase(itBond);
  }
}